<?php
namespace GFPHP;
if (!defined('__ROOT__')) exit('Sorry,Please from entry!');

/**
 * 模板引擎
 * 创建时间：2014-08-11 10:16 PGF 把以前写好的搬了过来，使模板可以使用静态缓存
 * 修改时间：2014-10-02 10:25 PGF 根据修改的缓存做出修改
 * 修改时间：2015-05-18 14:34 PGF 增加编译功能
 * 修改时间: 2016-03-20 11:09 PGF 添加fetch方法
 */
class Template
{
    /**
     * 模板中的变量
     * @var array
     */
    public $var = array();

    /**
     * 将默认的模板数据填充进去
     * Template constructor.
     */
    public function __construct()
    {
        $this->var['view_vars'] = Config::view_vars();
    }

    /**
     * 传入模板内容,返回模板编译执行后的内容
     * @param $templateCon
     * @return mixed
     */
    public function fetch($templateCon)
    {
        $template = '_tmp' . DIRECTORY_SEPARATOR . time() . random('6');
        /** @var string $template */
        $template_c = $this->get_path($template, 'view_c');
        $this->write($template_c, $this->template_parse($templateCon));
        foreach ($this->var as $k => $v) {
            $$k = $v;
        }
        ob_start();
        include $template_c;
        $content = ob_get_contents();
        ob_end_clean();
        unlink($template_c);
        return $content;
    }

    /**
     * 引用模板
     * @param $template
     * @param $cacheTime
     * @param $cacheKey
     */
    public function display($template, $cacheTime = FALSE, $cacheKey = FALSE)
    {
        $path['template_c'] = $this->get_path($template, 'view_c');
        $path['template'] = $this->get_path($template);
        //当缓存时间未设置时，将自动获取配置中的缓存时间
        $cache = $cacheTime ? intval($cacheTime) : Config::template('view_cache_time');
        $cache = isset($_POST) && !empty($_POST) ? 0 : $cache;
        $kVar = empty($cacheKey) ? NULL : $cacheKey;
        if (file_exists($path['template'])) {
            //如果已编译模板的不存在或者模板修改时间大于已编译模板的时间将重新编译
            if (!file_exists($path['template_c']) || filemtime($path['template']) > filemtime($path['template_c']))
                $this->write($path['template_c'], $this->template_parse(file_get_contents($path['template'])));
            if (($cache > 0 || $cache < 0) && Config::template('view_cache')) {
                if (!Cache::is_cache($this->get_temp_name($template, $cacheKey), Config::template('view_cache_dir'))) {

                    $content = self::cache_compile($template, $cacheKey);
                    $kVar = $kVar == '' ? '' : '[' . $kVar . ']';
                    debug::add('Template:写入缓存 ' . $template . $kVar . ' 缓存时间:' . $cache . '秒.');

                } elseif (($cache < 0 || Cache::time($this->get_temp_name($template, $cacheKey), Config::template('view_cache_dir')) + $cache > time()) && filemtime($path['template_c']) < Cache::time($this->get_temp_name($template, $cacheKey), Config::template('view_cache_dir'))) {
                    $content = Cache::get($this->get_temp_name($template, $cacheKey), Config::template('view_cache_dir'));
                    $kVar = $kVar == '' ? '' : '[' . $kVar . ']';
                    debug::add('Template:读取缓存 ' . $template . $kVar . ' 缓存时间:' . $cache . '秒.');

                } else {
                    $content = self::cache_compile($template, $cacheKey);
                    $kVar = $kVar == '' ? '' : '[' . $kVar . ']';
                    debug::add('Template:更新缓存 ' . $template . $kVar . ' 缓存时间:' . $cache . '秒.');

                }
            } else {

                foreach ($this->var as $k => $v) {
                    $$k = $v;
                }
                ob_start();
                include $path['template_c'];
                $content = ob_get_contents();
                ob_end_clean();
                debug::add('Template:使用模板 ' . $template . ' 未使用缓存.');
            }
            echo $content;
        } else {
            debug::add('Template:模板 ' . $path['template'] . ' 不存在.');

        }
    }

    /**
     * 获取路径
     * @param $templateName
     * @param string $type
     * @param bool $key KEY
     * @return string
     */
    private function get_path($templateName, $type = 'template', $key = FALSE)
    {
        switch ($type) {
            case 'template':
                $path = __ROOT__ . parseDir(Config::config('app_dir'), Config::template('view_dir'), Config::template('view_name')) . $templateName . Config::template('view_suffix');
                if (!$fileexits = file_exists($path))     //如果不存在，则查看默认模板是否存在
                {
                    if (Config::template('view_name') != Config::template('default_view_name')) {
                        $dpath = __ROOT__ . parseDir(Config::config('app_dir'), Config::template('view_dir'), Config::template('default_view_name')) . $templateName . Config::template('view_suffix');
                        if ($fileexits = file_exists($dpath)) {
                            return $dpath;
                        }
                    }
                    if ($fileexits == FALSE) {
                        $parseTemp = explode('/', $templateName);
                        $module = array_shift($parseTemp);
                        $tempname = implode('/', $parseTemp);
                        $dpath = __ROOT__ . parseDir(Config::config('app_dir'), Config::config('Module_dir'), $module, 'view') . $tempname . Config::template('view_suffix');
                        if ($fileexits = file_exists($dpath)) {
                            return $dpath;
                        }
                    }
                }

                return $path;
            case 'cache':

                return __ROOT__ . parseDir(Config::config('app_dir'), Config::cache('cache_dir'), Config::template('cache_dir'), Config::template('cache_dir'), Config::template('view_cache_dir'), Config::template('view_name')) . '/' . $templateName . $key;

            case 'view_c':

                return __ROOT__ . parseDir(Config::config('app_dir'), Config::cache('cache_dir'), Config::template('view_c_dir'), Config::template('view_name')) . $templateName . '.php';

        }
        return '';
    }

    /**
     * 写入文件
     * 模板静态缓存不使用此方法
     * @param $path
     * @param $content
     * @return int
     */
    private function write($path, $content)
    {
        $dir = dirname($path);
        //echo $dir;exit;
        if (!is_dir($dir))
            mkdir($dir, 0777, TRUE);

        /** @var string $path */
        return file_put_contents($path, $content);
    }

    /**
     * @param $key
     * @return string
     */
    public function get_var($key)
    {
        return isset($this->var[ $key ]) ? $this->var[ $key ] : '';
    }

    /**
     * 编译模板
     * @param $str    模板内容
     * @return string 编译后的模板内容
     */
    private function template_parse($str)
    {

        $str = Hooks::filter('GFPHP_template_parse_start',array($str));
        $str = Hooks::filter('GFPHP_template_parse_end',array($str));
        return $str;
    }


    ///=================获取文件位置======================///

    /**
     * @param $template
     * @param $cacheKey
     * @return string
     */
    private function get_temp_name($template, $cacheKey)
    {
        if ($cacheKey)
            return $template . '-' . $cacheKey;
        else
            return $template;
    }

    /**
     * @param $thisistemplatename
     * @return string
     */
    private function runtemp($thisistemplatename)
    {

        foreach ($this->var as $k => $v) {
            $$k = $v;
        }
        ob_start();

        include $this->get_path($thisistemplatename, 'view_c');

        $content = ob_get_contents();

        ob_end_clean();

        return $content;
    }

    /**
     * 编译保存静态缓存
     * @param string $template template_c
     * @param string $cacheKey template_key
     * @return string
     */
    private function cache_compile($template, $cacheKey)
    {
        $content = $this->runtemp($template);
        Cache::set($this->get_temp_name($template, $cacheKey), $content, Config::template('view_cache_dir'));

        return $content;
    }

    /**
     * 设置变量
     * 一个参数时必须为数组
     * 两个参数是第一个是定义的变量名，第二个是值
     * @param $data
     */
    public function assign($data)
    {
        $nums = func_num_args();
        if ($nums == 1) {
            if (is_array($data)) {
                foreach ($data as $k => $v) {
                    $this->var[ $k ] = $v;
                }
            }
        } else {
            $this->var[ func_get_arg(0) ] = func_get_arg(1);
        }

        return;
    }
}

//====================    END template.class.php      ========================//